package cn.com.nes.site.service.project.impl;

import cn.com.nes.common.exception.IllegalBusinessException;
import cn.com.nes.common.exception.MissBusinessParameterException;
import cn.com.nes.common.util.XzqhUtils;
import cn.com.nes.mybatis.agent.project.entity.ProjectServiceUserAreaCode;
import cn.com.nes.mybatis.agent.project.mapper.ProjectServiceUserAreaCodeMapper;
import cn.com.nes.mybatis.agent.system.entity.SystemXzqh;
import cn.com.nes.site.controller.project.vo.DelProjectServiceUserVO;
import cn.com.nes.site.entity.bo.project.SetServiceUserAreaCodeBO;
import cn.com.nes.site.entity.em.DeleteEnum;
import cn.com.nes.site.service.project.ProjectServiceUserAreaCodeService;
import cn.com.nes.site.service.project.dto.ProjectServiceUserDTO;
import cn.com.nes.site.service.system.region.XzqhService;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ProjectServiceUserAreaCodeServiceImpl extends ServiceImpl<ProjectServiceUserAreaCodeMapper, ProjectServiceUserAreaCode> implements ProjectServiceUserAreaCodeService {

    @Resource
    XzqhService xzqhService;

    /**
     * 查询施工人id List
     */
    @Override
    public List<Long> getAuthIdListByAreaCode(String serviceAreaCode) {
        QueryWrapper<ProjectServiceUserAreaCode> wrapper = new QueryWrapper<>();
        wrapper.eq("deleted", 0);
        wrapper.eq("service_area_code", serviceAreaCode);
        wrapper.select("auth_id");

        List<ProjectServiceUserAreaCode> projectServiceUserAreaCodes = this.list(wrapper);
        if (CollectionUtil.isEmpty(projectServiceUserAreaCodes)) {
            return Collections.emptyList();
        }
        return projectServiceUserAreaCodes.stream()
                .map(ProjectServiceUserAreaCode::getAuthId)
                .distinct()
                .collect(Collectors.toList());
    }

    /**
     * 设置服务区域
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void setAreaCode(SetServiceUserAreaCodeBO bo) throws Exception {
        if (CollectionUtil.isEmpty(bo.getAreaCodeList())) {
            throw new Exception("areaCodeList must not be null");
        }

        List<String> insertAreaCodeList = new ArrayList<>();
        List<Long> delServiceUserAreaCodeIdList = new ArrayList<>();

        // 检查是否需要修改行政区划编码 - 如果不需要就直接return
        QueryWrapper<ProjectServiceUserAreaCode> wrapper = new QueryWrapper<>();
        wrapper.eq("auth_id", bo.getAuthId());
        wrapper.eq("deleted", false);
        List<ProjectServiceUserAreaCode> projectServiceUserAreaCodes = this.list(wrapper);
        if (CollectionUtil.isNotEmpty(projectServiceUserAreaCodes)) {
            for (String areaCode : bo.getAreaCodeList()) {
                long count = projectServiceUserAreaCodes.stream()
                        .map(ProjectServiceUserAreaCode::getServiceAreaCode)
                        .distinct()
                        .filter(n -> n.equals(areaCode))
                        .count();
                if (count == 0) {
                    insertAreaCodeList.add(areaCode);
                }
            }
            for (ProjectServiceUserAreaCode serviceUserAreaCode : projectServiceUserAreaCodes) {
                long count = bo.getAreaCodeList()
                        .stream()
                        .filter(n -> n.equals(serviceUserAreaCode.getServiceAreaCode()))
                        .count();
                if (count == 0) {
                    delServiceUserAreaCodeIdList.add(serviceUserAreaCode.getId());
                }
            }
        } else {
            insertAreaCodeList = bo.getAreaCodeList();
        }

        // 删除所有旧的行政区划编码
        if (CollectionUtil.isNotEmpty(delServiceUserAreaCodeIdList)) {
            List<ProjectServiceUserAreaCode> deleteBatchList = new ArrayList<>();
            for (Long id : delServiceUserAreaCodeIdList) {
                ProjectServiceUserAreaCode deleteProjectServiceUserAreaCode = new ProjectServiceUserAreaCode();
                deleteProjectServiceUserAreaCode.setId(id);
                deleteProjectServiceUserAreaCode.setDeleted(DeleteEnum._1.getKey()); // 1-true
                deleteProjectServiceUserAreaCode.setGmtModifiedId(bo.getOperateUserId());
                deleteProjectServiceUserAreaCode.setGmtModified(bo.getOperateDate());
                deleteBatchList.add(deleteProjectServiceUserAreaCode);
            }
            this.updateBatchById(deleteBatchList);
        }

        // 新增服务范围行政区划代码
        if (CollUtil.isNotEmpty(insertAreaCodeList)) {
            List<ProjectServiceUserAreaCode> insertBatchList = new ArrayList<>();
            // 保存所有新的行政区划代码
            for (String areaCode : insertAreaCodeList) {
                ProjectServiceUserAreaCode projectServiceUserAreaCode = new ProjectServiceUserAreaCode();
                projectServiceUserAreaCode.setAuthId(bo.getAuthId());
                projectServiceUserAreaCode.setServiceAreaCode(areaCode);
                projectServiceUserAreaCode.setDeleted(DeleteEnum._0.getKey());
                projectServiceUserAreaCode.setGmtCreateId(bo.getOperateUserId());
                projectServiceUserAreaCode.setGmtCreate(bo.getOperateDate());
                insertBatchList.add(projectServiceUserAreaCode);
            }
            if (!this.saveOrUpdateBatch(insertBatchList)) {
                throw new IllegalBusinessException("服务区域保存失败！");
            }
        }
    }

    /**
     * 查询项目人员分包的区域信息
     */
    @Override
    public void setServiceUserAreaCode(List<ProjectServiceUserDTO> projectServiceUserList) {
        if (CollectionUtil.isEmpty(projectServiceUserList)) {
            return;
        }

        for (ProjectServiceUserDTO projectServiceUserDTO : projectServiceUserList) {
            // 查询关联的全部区域信息
            QueryWrapper<ProjectServiceUserAreaCode> wrapper = new QueryWrapper<>();
            wrapper.eq("auth_id", projectServiceUserDTO.getId());
            wrapper.eq("deleted", false);
            List<ProjectServiceUserAreaCode> projectServiceUserAreaCodes = this.list(wrapper);
            // 处理区域信息
            if (CollectionUtil.isNotEmpty(projectServiceUserAreaCodes)) {
                projectServiceUserDTO.setServiceAreaCode(projectServiceUserAreaCodes.stream()
                        .map(ProjectServiceUserAreaCode::getServiceAreaCode)
                        .collect(Collectors.joining(";")));
                List<String> areaNamelist = new ArrayList<>();
                for (ProjectServiceUserAreaCode projectServiceUserAreaCode : projectServiceUserAreaCodes) {
                    String areaName = xzqhService.getAreaName(projectServiceUserAreaCode.getServiceAreaCode());
                    if (StrUtil.isNotBlank(areaName)) {
                        areaNamelist.add(areaName);
                    }
                }
                projectServiceUserDTO.setServiceAreaCodeName(String.join(",", areaNamelist));
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteByAuthId(DelProjectServiceUserVO vo) throws Exception {
        QueryWrapper<ProjectServiceUserAreaCode> wrapper = new QueryWrapper<>();
        wrapper.eq("auth_id", vo.getId());
        wrapper.eq("deleted", false);
        wrapper.select("id");
        List<ProjectServiceUserAreaCode> projectServiceUserAreaCodes = this.baseMapper.selectList(wrapper);
        if (CollectionUtil.isEmpty(projectServiceUserAreaCodes)) {
            return;
        }
        // 取出id挨个删除
        List<Long> idList = projectServiceUserAreaCodes.stream()
                .map(ProjectServiceUserAreaCode::getId)
                .distinct()
                .collect(Collectors.toList());
        for (Long id : idList) {
            ProjectServiceUserAreaCode projectServiceUserAreaCode = new ProjectServiceUserAreaCode();
            projectServiceUserAreaCode.setId(id);
            projectServiceUserAreaCode.setDeleted(DeleteEnum._1.getKey());
            projectServiceUserAreaCode.setGmtModified(vo.getOperateDate());
            projectServiceUserAreaCode.setGmtModifiedId(vo.getOperateUserId());
            Integer rows = this.baseMapper.updateById(projectServiceUserAreaCode);
            if (1 != rows) {
                throw new Exception("删除施工队员负责区域信息失败!");
            }
        }
    }

    @Override
    public List<ProjectServiceUserAreaCode> getList(Long authId) throws Exception {
        if (ObjectUtil.isNull(authId)) {
            return Collections.emptyList();
        }

        QueryWrapper<ProjectServiceUserAreaCode> wrapper = new QueryWrapper<>();
        wrapper.eq("auth_id", authId);
        wrapper.eq("deleted", false);
        return this.list(wrapper);
    }

    @Override
    public List<String> getServiceAreaCodes(Long authId) throws Exception {
        if (ObjectUtil.isNull(authId)) {
            throw new MissBusinessParameterException("authId must not null");
        }
        List<ProjectServiceUserAreaCode> projectServiceUserAreaCodes = this.getList(authId);
        if (projectServiceUserAreaCodes.isEmpty()) {
            return Collections.emptyList();
        }

        // 获取当前权限的行政区划
        List<String> setAreaCodes = projectServiceUserAreaCodes.stream()
                .map(ProjectServiceUserAreaCode::getServiceAreaCode)
                .distinct()
                .collect(Collectors.toList());
        List<SystemXzqh> systemXzqhs = (List<SystemXzqh>) xzqhService.listByIds(setAreaCodes);

        // 1、只有上级代码，获取所有子行政区划
        // 2、有上级及部分下级代码，获取下级的所有行政区划代码
        for (SystemXzqh systemXzqh : systemXzqhs) {
            // 获取当前行政区划代码级别
            String regionCodePrefix = XzqhUtils.getRegionCodePrefix(systemXzqh.getXzqhdm());
            // List<SystemXzqh> collect = systemXzqhs.stream()
            //         .filter(xzqh -> !xzqh.getXzqhdm().equals(systemXzqh.getXzqhdm()))
            //         .collect(Collectors.toList());
            // boolean match = collect.stream().anyMatch(xzqh -> xzqh.getXzqhdm().startsWith(regionCodePrefix));
            boolean match = systemXzqhs.stream()
                    .filter(xzqh -> !xzqh.getXzqhdm().equals(systemXzqh.getXzqhdm()))
                    .anyMatch(xzqh -> xzqh.getXzqhdm()
                            .startsWith(regionCodePrefix));
            if (match) {
                log.info("符合匹配 - {}", systemXzqh.getXzqhdm());
            } else {
                List<SystemXzqh> areacodes = xzqhService.getListByPrefix(regionCodePrefix);
                if (CollUtil.isNotEmpty(areacodes)) {
                    setAreaCodes.addAll(areacodes.stream().map(SystemXzqh::getXzqhdm).filter(xzqh -> !xzqh.equals(systemXzqh.getXzqhdm())).collect(Collectors.toList()));
                }
            }
        }
        return setAreaCodes.stream().distinct().collect(Collectors.toList());
    }

}
